package com.nd.android.u.ui.business4starapp;

import ims.utils.IMLogUtils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;


import android.text.TextUtils;

import com.common.StarAppConfig;
import com.common.allCommon.MD5Arithmetic;
import com.nd.android.u.allCommonHttp.HttpException;
import com.nd.android.u.chatInterfaceImpl.ChatInterfaceImpl;
import com.nd.android.u.controller.ChatGlobalVariable;
import com.nd.android.u.controller.innerInterface.IUploadListener;
import com.product.android.business.config.Configuration;

/**
 * 文件上传下载通讯类
 * <br>Created 2014-9-9 下午10:04:33
 * @version  
 * @author   cb		
 * @see 	 
 */
public class FileCom {
    public static final String CREATEURL = "ofs/upload_c_rest.php";
    public static final String UPDATEURL = "ofs/upload_u_rest.php";
    public static final String ENDURL = "ofs/upload_e_rest.php";
    public static final String TRANSMIT_URL = "ofs/carry.php";

    public static final String FILE_BASE_URL = StarAppConfig.getConfig(StarAppConfig.FILE_STORAGE_SYSTEM_SERVICE);//"http://99img.com"
    public static final String FILE_DOWN_URL = FILE_BASE_URL + "show/file/fid/";

//    private HttpComExt mOapHtppApi;

    public static class FileUploadEntity {
        public static final int DEFAULT_PACKAGESIZE = 8192;// 默认封包大小为8K
        public static final int MIN_PACKAGESIZE = 1024;// 最小封包大小为1K
        public StringBuilder errMsg = new StringBuilder(); // 错误信息
        public File file = null; // 上传的文件
        public String sid = ""; // 当前的uapsid
        public String md5;
        public int id = 68;
        public String fileName;
        public String fid;

        // public String url = ChatConfiguration.getShareFileServiceUrl() + FileCom.UPDATEURL; //
        // 上传的地址
        public String url = FILE_BASE_URL + "files"; // 上传的地址
        public int packageSize = DEFAULT_PACKAGESIZE; // 每一次上传的包的大小
        public int shiftCount = 1; // 上传失败之后封包的右位位数，用于减小每一次封包
        public int repeatTimes = 3; // 重试的次数，默认是3次
        public int nowTry = 0; // 当前正在第几次尝试
        public long curPos = 0; // 已上传的文件大小
        public boolean isUploadSuccess = false; // 上传是否成功
    }

    public FileCom(String uapSid) {
//        mOapHtppApi = new HttpComExt(uapSid);
    }

    private IUploadListener mUploadListener;

    public void setOnUploadListener(IUploadListener listener) {
        mUploadListener = listener;
    }

    /**
     * @n<b>函数名称</b> :doUpload
     * @brief 上传文件
     * @see
     * @version Ver 1.3.x
     * @param @param uploadEntity
     * @param @return
     * @param @throws HttpException
     * @return boolean
     * @<b>作者</b> : cb
     * @<b>创建时间</b> : 2013-12-10下午5:25:58
     */
    public boolean doUpload(FileUploadEntity uploadEntity) {

        try {
            for (int i = 0; i < uploadEntity.repeatTimes; i++) {
                uploadEntity.nowTry = i;
                if (uploadEntity.packageSize < FileUploadEntity.MIN_PACKAGESIZE) {
                    // 定个最小值
                    uploadEntity.packageSize = FileUploadEntity.MIN_PACKAGESIZE;
                }
                if (uploadFile(uploadEntity)) {
                    uploadEntity.isUploadSuccess = true;
                    break;
                }
            }
            if (!uploadEntity.isUploadSuccess) {
                // 上传失败
                if (mUploadListener != null) {
                    mUploadListener.onFail("upload file fail", 0);
                }
                return false;
            }
            if (mUploadListener != null) {
                mUploadListener.onSuccess("" + uploadEntity.fid);
            }
            return true;
        } catch (HttpException e) {
            e.printStackTrace();
            if (mUploadListener != null) {
                mUploadListener.onFail("upload fail:" + e.getMessage(), 0);
            }
        }
        return false;
    }

    /**
     * 设置参数
     * 
     * <br>
     * Created 2014-9-1 下午5:45:01
     * 
     * @param uploadEntity
     * @author youy
     */
    public void setSomeParam(FileUploadEntity uploadEntity) {
        try {
            // 登录
            String sid = ChatGlobalVariable.getInstance().mShareFileServiceSid;
            if (TextUtils.isEmpty(sid)) {
                // sid = loginShareFileService(uploadEntity.sid);
                sid = ChatInterfaceImpl.INSTANCE.chatCallOtherModel.getSid();
            }
            if (TextUtils.isEmpty(sid)) {
                sid = "";
            }
            if (!sid.equals(ChatGlobalVariable.getInstance().mShareFileServiceSid)) {
                ChatGlobalVariable.getInstance().mShareFileServiceSid = sid;
            }
            uploadEntity.sid = sid;
            uploadEntity.md5 = MD5Arithmetic.getFileMD5String(uploadEntity.file);
            uploadEntity.fileName = uploadEntity.file.getName();
        } catch (Exception e) {
            if (e != null) {
                uploadEntity.errMsg.append("createFile:" + uploadEntity.nowTry + " time,error:"
                        + e.getMessage() + "**");
            }
        }
    }

    public boolean uploadFile(FileUploadEntity uploadEntity) throws HttpException {
        InputStream is = null;
        InputStream in = null;
        DataOutputStream outStream = null;
        HttpURLConnection conn = null;
        File file = uploadEntity.file;
        if (file == null) {
            return false;
        }
        long fileSize = file.length();
        setSomeParam(uploadEntity);
        long uid = ChatInterfaceImpl.INSTANCE.chatCallOtherModel.getOapUid();
        try {
            byte[] buffer = new byte[uploadEntity.packageSize];
            int len = 0;
            URL uri = new URL(uploadEntity.url);
            is = new FileInputStream(file);
            is.skip(uploadEntity.curPos);
            // 计算分块数量
            double cf = (double) fileSize / uploadEntity.packageSize;
            double pos = 0.5d;
            if ((fileSize % uploadEntity.packageSize) == 0) {
                pos = 0;
            }
            long chunks = Math.round(cf + pos);
            int chunkId = 1;
            do {
                len = is.read(buffer, 0, uploadEntity.packageSize);
                if (-1 == len) {
                    // 上传成功
                    return true;
                }
                String BOUNDARY = java.util.UUID.randomUUID().toString();
                String PREFIX = "--", LINEND = "\r\n";
                String MULTIPART_FROM_DATA = "multipart/form-data";
                conn = (HttpURLConnection) uri.openConnection();
                conn.setReadTimeout(60 * 1000);
                conn.setDoInput(true); // 允许输入
                conn.setDoOutput(true); // 允许输出
                conn.setUseCaches(true);
                // conn.setRequestProperty("Cookie", "PHPSESSID="
                // + ChatGlobalVariable.getInstance().mShareFileServiceSid);
                conn.setRequestProperty("Cookie", "SID=" + uploadEntity.sid);
                conn.setRequestProperty("CLOUDID", Configuration.CLOUNDID);
                conn.setRequestProperty("APPID", "233");

                conn.setRequestMethod("POST"); // Post方式
                conn.setRequestProperty("connection", "keep-alive");
                conn.setRequestProperty("Charsert", "UTF-8");
                conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary="
                        + BOUNDARY);

                Map<String, String> params = new HashMap<String, String>();
                params.put("type", "3");
                params.put("sid", uploadEntity.sid);
                params.put("id", uploadEntity.id + "");
                params.put("path", "/" + uid);
                params.put("md5", uploadEntity.md5);
                params.put("name", uploadEntity.fileName);
                params.put("size", fileSize + "");
                params.put("chunks", chunks + "");
                params.put("chunk_id", chunkId + "");
                params.put("chunk_size", len + "");
                params.put("range_pos", uploadEntity.curPos + "");

                // 首先组拼文本类型的参数
                StringBuilder sb = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    sb.append(PREFIX);
                    sb.append(BOUNDARY);
                    sb.append(LINEND);
                    sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\""
                            + LINEND);
                    sb.append(LINEND);
                    sb.append(entry.getValue());
                    sb.append(LINEND);

                }
                outStream = new DataOutputStream(conn.getOutputStream());
                outStream.write(sb.toString().getBytes());
                // 发送文件数据
                if (file != null) {
                    StringBuilder sb1 = new StringBuilder();
                    sb1.append(PREFIX);
                    sb1.append(BOUNDARY);
                    sb1.append(LINEND);
                    sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + 0
                            + "\"" + LINEND);
                    sb1.append("Content-Type: application/octet-stream" + LINEND);

                    sb1.append(LINEND);

                    outStream.write(sb1.toString().getBytes());
                    outStream.write(buffer, 0, len);

                    outStream.write(LINEND.getBytes());
                }
                // 请求结束标志
                byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
                outStream.write(end_data);
                outStream.flush();

                // 得到响应码
                int res = conn.getResponseCode();
                in = conn.getInputStream();
                if (res == 200) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    String line = null;
                    String sMsg = "";
                    while ((line = reader.readLine()) != null) {
                        sMsg += line;
                    }
                    IMLogUtils.i("test", "sMsg:" + sMsg);
                    JSONObject resJson = new JSONObject(sMsg);
                    if (!resJson.has("code")) {
                        int status = resJson.getInt("status");
                        if (status == 1 || status == 2) {// 上传成功
                            uploadEntity.curPos += len;
                            chunkId ++;
                            if (mUploadListener != null) {
                                mUploadListener.onProgressed(uploadEntity.curPos, fileSize);
                            }
                            if (status == 2) {
                                long fid = resJson.getLong("fid");
                                uploadEntity.fid = fid + "";
                                reader.close();
                                return true;
                            }
                        } else {// 上传失败
                            uploadEntity.errMsg.append("uploadFile:" + getResponseErrMsg(sMsg));
                            reader.close();
                            return false;
                        }
                    } else {// 上传失败
                        uploadEntity.errMsg.append("uploadFile:" + getResponseErrMsg(sMsg));
                        reader.close();
                        return false;
                    }
                } else {
                    throw new HttpException("error response code");
                }
            } while (true);
        } catch (IOException e) {
            // 连接超时，可能封包太大，修改封包大小
            uploadEntity.errMsg.append("uploadFileUpdate:" + uploadEntity.nowTry + " time,error:"
                    + e.getMessage() + ",uploadEntity.packageSize:" + uploadEntity.packageSize
                    + "**");
            uploadEntity.packageSize = uploadEntity.packageSize >> uploadEntity.shiftCount;
            return false;
        } catch (JSONException e) {
            e.printStackTrace();
            uploadEntity.errMsg.append("uploadFile:" + e.getMessage());
            return false;
        } finally {
            try {
                if (is != null)
                    is.close();
                if (in != null)
                    in.close();
                if (outStream != null)
                    outStream.close();
                if (conn != null)
                    conn.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

//    // 登录
//    public String loginShareFileService(String uapSid) throws HttpException {
//        String url = ChatConfiguration.getShareFileServiceUrl() + "check.php?s=" + uapSid;
//        JSONObject object = mOapHtppApi.getAndReloginIfNeed(url, uapSid).asJSONObject();
//        String sid = "";
//        if (object == null) {
//            throw new HttpException("loginShareFileService fail");
//        } else {
//            try {
//                int result = object.getInt("result");
//                if (result != 200) {
//                    if (result == 406) {
//                        // 如果sid无效，服务端会返回406，需要重新登录一次获取新的SID
//                        // String newUapSid =
//                        // CommonInterfaceManager.INSTANCE.reloginInterface.onGetReloginSid();
//                        BaseCommonStruct msg = new BaseCommonStruct();
//                        int ret2 = CommonInterfaceManager.INSTANCE.CommonInterfaceID(
//                                CIConst.MAIN_MODELID, CIConst.MAIN_ON_GET_RELOGINSID_91002, msg);
//                        String newUapSid = "";
//                        if (ret2 == 0 && (msg.obj2 instanceof String)) {
//                            newUapSid = (String) msg.obj2;
//                        }
//
//                        if (!TextUtils.isEmpty(newUapSid)) {
//                            url = ChatConfiguration.getShareFileServiceUrl() + "check.php?s="
//                                    + newUapSid;
//                            object = mOapHtppApi.get(url).asJSONObject();
//                            if (object == null) {
//                                throw new HttpException("loginShareFileService fail");
//                            } else {
//                                result = object.getInt("result");
//                                // 重登录后仍然失败，抛异常
//                                if (result != 200) {
//                                    throw new HttpException("loginShareFileService fail:"
//                                            + object.getString("errorinfo"));
//                                }
//                            }
//                        }
//                    } else {
//                        throw new HttpException("loginShareFileService fail:"
//                                + object.getString("errorinfo"));
//                    }
//                }
//                sid = object.getString("sid");
//            } catch (JSONException e) {
//                throw new HttpException("loginShareFileService fail:json error");
//            }
//
//        }
//        return sid;
//    }

    final String multipart_form_data = "multipart/form-data";
    final String twoHyphens = "--";
    final String boundary = "****************fD4fH3gL0hK7aI6";
    final String lineEnd = System.getProperty("line.separator"); // The value is "\r\n" in Windows.

    /**
     * @n<b>函数名称</b> :transmitFile
     * @brief 文件换KEY
     * @see
     * @version Ver 1.3.x
     * @param @param uidAndKey
     * @param @param errorMsg
     * @param @return
     * @return String
     * @<b>作者</b> : cb
     * @<b>创建时间</b> : 2013-12-10下午5:36:19
     */
    public String transmitFile(String uidAndKey, StringBuilder errorMsg) {
       /* String url = ChatConfiguration.getShareFileServiceUrl() + TRANSMIT_URL + uidAndKey;
        String fkey = "";
        JSONObject object;
        try {
            String loginsid = loginShareFileService(ChatInterfaceImpl.INSTANCE.chatCallOtherModel.getSid());
            if (!TextUtils.isEmpty(loginsid)) {
                HttpComExt comExt = new HttpComExt(loginsid);
                object = comExt.get(url).asJSONObject();
                if (object == null) {
                    throw new HttpException("transmitFile fail");
                } else {
                    int result = object.getInt("result");
                    if (result != 200) {
                        throw new HttpException("transmitFile fail:"
                                + object.getString("errorinfo"));
                    }
                    fkey = object.getString("fkey");
                    if (mUploadListener != null) {
                        mUploadListener.onSuccess(fkey);
                    }
                    return fkey;
                }
            } else {
                errorMsg.append("loginShareFileService fail");
            }
        } catch (ResponseException e1) {
            e1.printStackTrace();
            errorMsg.append(e1.getMessage());
        } catch (HttpException e1) {
            e1.printStackTrace();
            errorMsg.append(e1.getMessage());
        } catch (JSONException e) {
            errorMsg.append(e.getMessage());
            e.printStackTrace();
        }
        if (mUploadListener != null) {
            mUploadListener.onFail(errorMsg.toString(), 0);
        }*/
//        return fkey;
        if (mUploadListener != null) {
            mUploadListener.onSuccess("" + uidAndKey);
        }
        return "";
    }

    /**
     * 获取错误码
     * 
     * <br>
     * Created 2014-9-1 下午5:01:55
     * 
     * @param result
     * @return
     * @author youy
     */
    public static String getResponseErrMsg(String result) {
        String res = "";
        try {
            JSONObject json = new JSONObject(result);
            if (json.has("msg")) {
                res = json.getString("msg");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }
}
